// 字符串的下划线格式转驼峰格式，eg：hello_world => helloWorld
const underline2Hump = (s) => {
	return s.replace(/_(\w)/g, (all, letter) => {
		return letter.toUpperCase()
	})
}

// 字符串的驼峰格式转下划线格式，eg：helloWorld => hello_world
const hump2Underline = (s) => {
	return s.replace(/([A-Z])/g, '_$1').toLowerCase()
}

// JSON对象的key值转换为驼峰式
const jsonToHump = (obj) => {
	if (obj instanceof Array || Array.isArray(obj)) {
		obj.forEach(function(v, i) {
			jsonToHump(v)
		})
	} else if (obj instanceof Object || isPlainObject(obj)) {
		Object.keys(obj).forEach(function(key) {
			var newKey = underline2Hump(key)
			if (newKey !== key) {
				obj[newKey] = obj[key]
				delete obj[key]
			}
			jsonToHump(obj[newKey])
		})
	}
}

// JSON对象的key值转换为下划线格式
const jsonToUnderline = (obj) => {
	if (obj instanceof Array || Array.isArray(obj)) {
		obj.forEach(function(v, i) {
			jsonToUnderline(v)
		})
	} else if (obj instanceof Object || isPlainObject(obj)) {
		Object.keys(obj).forEach(function(key) {
			var newKey = hump2Underline(key)
			if (newKey !== key) {
				obj[newKey] = obj[key]
				delete obj[key]
			}
			jsonToUnderline(obj[newKey])
		})
	}
}

const isPlainObject = (obj) => {
	let proto;
	let Ctor;
	// (1) null 肯定不是 Plain Object
	// (2) 使用 Object.property.toString 排除部分宿主对象，比如 window、navigator、global
	if (!obj || ({}).toString.call(obj) !== "[object Object]") {
		return false;
	}
	proto = Object.getPrototypeOf(obj);
	// 只有从用 {} 字面量和 new Object 构造的对象，它的原型链才是 null
	if (!proto) {
		return true;
	}
	// (1) 如果 constructor 是对象的一个自有属性，则 Ctor 为 true，函数最后返回 false
	// (2) Function.prototype.toString 无法自定义，以此来判断是同一个内置函数
	Ctor = ({}).hasOwnProperty.call(proto, "constructor") && proto.constructor;
	return typeof Ctor === "function" && Function.prototype.toString.call(Ctor) === Function.prototype.toString.call(Object);
}

export {
	underline2Hump,
	hump2Underline,
	jsonToHump,
	jsonToUnderline
}
